<!DOCTYPE html>
<html>
    
<head>
    <meta charset="utf-8">
    
    <title>这15个Android开源库，只有经常逛Github的才知道！ | ApocalypseBlog</title>
    <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    

    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1.14.0.css">

    <script src="/javascripts/bubble.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            
        }
        window.aomori_logo_typed_animated = false
        window.aomori_search_algolia = false

    </script>
<script>
    ((window.gitter = {}).chat = {}).options = {
      room: 'ApocalypseBlog/Apocalypse'
    };
  </script>
  <script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
<meta name="generator" content="Hexo 5.3.0"></head>
<!--DaoVoice服务http://blog.daovoice.io/-->

    <script>(function (i, s, o, g, r, a, m) {
        i['DaoVoiceObject'] = r;
        i[r] = i[r] ||
          function () {
            (i[r].q = i[r].q || []).push(arguments);
          };
        i[r].l = 1 * new Date();
        a = s.createElement(o);
        m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        a.charset = 'utf-8';
        m.parentNode.insertBefore(a, m);
      })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/b00f5052.js", 'daovoice');
      daovoice('init', {
        app_id: "b00f5052",
      });
      daovoice('update');
    </script>
  
<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-inner">
                
                    <a class="header-type-title" href="/">ApocalypseBlog</a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
            </div>
            <div class="header-menu-social">
                
            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckk6o6aw200157knyhndybhm7" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      这15个Android开源库，只有经常逛Github的才知道！
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2020-08-03T09:15:32.000Z" itemprop="datePublished">2020-08-03</time>
</div>

            

            

            

        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <h3 id="1-Coil"><a href="#1-Coil" class="headerlink" title="1. Coil"></a>1. Coil</h3><p><img src="http://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c92c5e5fad0490ab9e0d2364676e2f8~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p>
<p>Coil是Android上的一个全新的图片加载框架，它的全名叫做<code> coroutine image loader</code>,即协程图片加载库。与传统的图片加载库Glide，Picasso或Fresco等相比。该具有轻量（只有大约1500个方法）、快、易于使用、更现代的API等优势。</p>
<a id="more"></a>

<p>它支持GIF和SVG，并且可以执行四个默认转换：<code>模糊</code>，<code>圆形裁剪</code>，<code>灰度</code>和<code>圆角</code>。</p>
<p>示例如下：</p>
<pre><code class="kotlin">imageView.load(“https://www.example.com/image.jpg&quot;) &#123;
 crossfade(true)
 placeholder(R.drawable.image)
 transformations(CircleCropTransformation())
&#125;
</code></pre>
<p>并且是全用Kotlin编写，如果你是纯Kotlin项目的话，那么这个库应该是你的首选。</p>
<p>Github地址：<a target="_blank" rel="noopener" href="https://github.com/coil-kt/coil">github.com/coil-kt/coi…</a></p>
<h3 id="2-MultiSearchView"><a href="#2-MultiSearchView" class="headerlink" title="2. MultiSearchView"></a>2. MultiSearchView</h3><p><img src="http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cef0256e09bf4116a1724450423302ca~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p>
<p>该库具有一个非常酷的<code>Search View </code>动画！</p>
<p>使用非常简单，并且可以自定义，你可以在在<code>styles.xml</code>下添加自定义样式。</p>
<p>示例代码：</p>
<pre><code class="xml">&lt;com.iammert.library.ui.multisearchviewlib.MultiSearchView
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;/&gt;     

multiSearchView.setSearchViewListener(object : MultiSearchView.MultiSearchViewListener&#123;
    override fun onItemSelected(index: Int, s: CharSequence) &#123;
    &#125;

    override fun onTextChanged(index: Int, s: CharSequence) &#123;
    &#125;

    override fun onSearchComplete(index: Int, s: CharSequence) &#123;
    &#125;

    override fun onSearchItemRemoved(index: Int) &#123;
    &#125;

&#125;)
</code></pre>
<p>自定义样式：</p>
<pre><code class="xml">  &lt;!-- Search Text Style. --&gt;
    &lt;style name=&quot;SearchTextStyle&quot;&gt;
        &lt;!-- Custom values write to here for SearchEditText. --&gt;
        &lt;item name=&quot;android:focusable&quot;&gt;true&lt;/item&gt;
        &lt;item name=&quot;android:focusableInTouchMode&quot;&gt;true&lt;/item&gt;
        &lt;item name=&quot;android:enabled&quot;&gt;true&lt;/item&gt;
        &lt;item name=&quot;android:hint&quot;&gt;Search&lt;/item&gt;
        &lt;item name=&quot;android:imeOptions&quot;&gt;actionSearch&lt;/item&gt;
        &lt;item name=&quot;android:textSize&quot;&gt;18sp&lt;/item&gt;
        &lt;item name=&quot;android:maxLength&quot;&gt;15&lt;/item&gt;
        &lt;item name=&quot;android:inputType&quot;&gt;textCapSentences&lt;/item&gt;
        &lt;item name=&quot;android:textColorHint&quot;&gt;#80999999&lt;/item&gt;
        &lt;item name=&quot;android:textColor&quot;&gt;#000&lt;/item&gt;
    &lt;/style&gt;
</code></pre>
<p>然后，您应该将样式设置为<code>MultiSearchView</code>下的<code>app：searchTextStyle</code>。</p>
<p>Github地址：<a target="_blank" rel="noopener" href="https://github.com/iammert/MultiSearchView">github.com/iammert/Mul…</a></p>
<h3 id="3-CalendarView"><a href="#3-CalendarView" class="headerlink" title="3. CalendarView"></a>3. CalendarView</h3><p><img src="http://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e1afbfa15f1d405b9de8e4e46e2b5d3f~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p>
<p><code>CalendarView</code>是一个高度可定制化的日历组件库，用recycleView实现。</p>
<p>它有如下特性：</p>
<ul>
<li>单一或范围选择</li>
<li>周历或者月历模式</li>
<li>边界日期</li>
<li>自定义日历视图</li>
<li>水平或者垂直滚动模式</li>
<li>完全可定制的视图</li>
</ul>
<p>该库的文档也非常全面，并包含许多示例。此外，还有一个示例应用程序展示了库的所有功能。</p>
<p>它是用纯Kotlin编写的，并在MIT许可下发布。如果您需要在应用程序中使用日历视图，这是一个不错的选择。</p>
<blockquote>
<p>注意：该库通过Java 8+ API使用了java.time类，以便向后兼容，因为这些类是在Java 8中添加的。</p>
</blockquote>
<p>因此，需要在app的<code>build.gradle</code> 中添加如下配置：</p>
<pre><code class="java">android &#123;
  defaultConfig &#123;
    // Required ONLY when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  &#125;

  compileOptions &#123;
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  &#125;
&#125;

dependencies &#123;
  coreLibraryDesugaring &#39;com.android.tools:desugar_jdk_libs:&lt;latest-version&gt;&#39;
&#125;
</code></pre>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/kizitonwose/CalendarView">github.com/kizitonwose…</a></p>
<h3 id="4-Bubble-Navigation"><a href="#4-Bubble-Navigation" class="headerlink" title="4. Bubble Navigation"></a>4. Bubble Navigation</h3><table>
<thead>
<tr>
<th>FloatingTopBarActivity</th>
<th>TopBarActivity</th>
</tr>
</thead>
<tbody><tr>
<td><img src="http://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/21aa4e875a3646c19d03245c3b16cdf2~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></td>
<td><img src="http://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d14b987ece1447e3973f9da391c9e9ff~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>BottomBarActivity</th>
<th>EqualBottomBarActivity</th>
</tr>
</thead>
<tbody><tr>
<td><img src="http://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d7fcd1e5012d4aceaaf4d44f67499121~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></td>
<td><img src="http://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9b93b20de4e04e0bb28c400b7b6b6b15~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></td>
</tr>
</tbody></table>
<p><code> Bubble Navigation</code>是一个轻巧的库，可通过大量自定义选项轻松制作精美的导航栏。</p>
<p>它有很多非常的特性：</p>
<ul>
<li>针对不同用例的两种类型的<code>NavigationViews</code>：<ul>
<li><code>BubbleNavigationConstraintView</code>（支持spread<code>spread</code>，<code>inside</code>, 和 <code>packed</code>莫斯）</li>
<li><code>BubbleNavigationLinearView</code>（允许平均分配，使用权重或packed模式）</li>
</ul>
</li>
<li>高度可定制化</li>
<li>您可以添加小红点，它具有<code>BubbleToggleView</code>来创建新的UI组件，而不仅仅是导航</li>
</ul>
<p>示例：</p>
<pre><code class="xml">&lt;com.gauravk.bubblenavigation.BubbleNavigationConstraintView
        android:id=&quot;@+id/top_navigation_constraint&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginBottom=&quot;380dp&quot;
        android:background=&quot;@color/white&quot;
        android:elevation=&quot;4dp&quot;
        android:padding=&quot;12dp&quot;
        app:bnc_mode=&quot;spread&quot;&gt;

        &lt;com.gauravk.bubblenavigation.BubbleToggleView
            android:id=&quot;@+id/c_item_rest&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            app:bt_active=&quot;true&quot;
            app:bt_colorActive=&quot;@color/search_active&quot;
            app:bt_colorInactive=&quot;@color/search_inactive&quot;
            app:bt_icon=&quot;@drawable/ic_restaurant&quot;
            app:bt_shape=&quot;@drawable/transition_background_drawable_restaurant&quot;
            app:bt_title=&quot;@string/restaurant&quot;
            app:bt_padding=&quot;@dimen/internal_padding&quot;
            app:bt_titlePadding=&quot;@dimen/title_padding&quot; /&gt;

         &lt;!-- Add more child items here - max upto 5 --&gt;

    &lt;/com.gauravk.bubblenavigation.BubbleNavigationConstraintView&gt;
</code></pre>
<p>Github文档很完善，有很多示例，更多用法和属性可去Github了解。</p>
<p>Github:<a target="_blank" rel="noopener" href="https://github.com/gauravk95/bubble-navigation">github.com/gauravk95/b…</a></p>
<h3 id="5-FabFilter"><a href="#5-FabFilter" class="headerlink" title="5. FabFilter"></a>5. FabFilter</h3><p><img src="http://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4b9a558a643f41dab51e884863656232~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p>
<p>这是一个有趣的项目，它不是一个直接可用的库，而是一个示例应用程序，展示了<code>使用</code>和<code>不使用</code> <code>MotionLayout</code>两种方式来实现的高级UI动画。</p>
<p>详细的实现细节可以看看Medium上的系列文章：</p>
<p><a target="_blank" rel="noopener" href="https://proandroiddev.com/complex-ui-animation-on-android-8f7a46f4aec4">“Complex UI/Animations on Android”</a></p>
<p><a target="_blank" rel="noopener" href="https://proandroiddev.com/complex-ui-animations-on-android-featuring-motionlayout-aa82d83b8660">“Complex UI/Animations on Android — featuring MotionLayout”</a></p>
<p>Github:<a target="_blank" rel="noopener" href="https://github.com/nikhilpanju/FabFilter">github.com/nikhilpanju…</a></p>
<h3 id="6-android-showcase"><a href="#6-android-showcase" class="headerlink" title="6.android-showcase"></a>6.android-showcase</h3><p><code>android-showcase</code>是一个非常优秀的开源项目，它是一个展示应用程序，展示了如何使用Kotlin和最新的Jetpack 技术栈来开发一个APP。</p>
<p>该项目为您带来了一系列最佳实践，工具和解决方案：</p>
<ul>
<li>100% Kotlin</li>
<li>现代架构 (feature modules, clean architecture, Model-View-ViewModel, Model-View-Intent)</li>
<li>Android Jetpack组件</li>
<li>单Activity模式，使用Navigation导航</li>
</ul>
<p>看完这个项目，在模块化，Clean体系结构，测试、设置CI / CD工具，等方面，你将会受到启发。感谢作者的开源。</p>
<p>Github：<a target="_blank" rel="noopener" href="https://github.com/igorwojda/android-showcase">github.com/igorwojda/a…</a></p>
<h3 id="7-Croppy"><a href="#7-Croppy" class="headerlink" title="7. Croppy"></a>7. Croppy</h3><p><code>Croppy</code>是一个Android图片裁剪库。</p>
<p>它有很多强大的特性：</p>
<ul>
<li>双指缩放</li>
<li>裁剪任意大小</li>
<li>按照长宽比例裁剪</li>
<li>显示裁剪后的Bitmap</li>
<li>自动居中裁剪</li>
<li>全面的动画使用体验</li>
</ul>
<p>更多使用细节请看Github。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/lyrebirdstudio/Croppy">github.com/lyrebirdstu…</a></p>
<h3 id="8-RubberPicker"><a href="#8-RubberPicker" class="headerlink" title="8. RubberPicker"></a>8. RubberPicker</h3><p><img src="http://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3514add953e34784b872a85ef31511c3~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p>
<p>一个炫酷的、有趣的SeekBar动画库。</p>
<p><code>RubberPicker</code>库包含<code>RubberSeekBar</code>和<code>RubberRangePicker</code>，其灵感来自<code>Cuberto</code>的<code>iOS橡胶范围选择器</code>。</p>
<p>使用示例：</p>
<p>布局文件中配置</p>
<pre><code class="xml">&lt;com.jem.rubberpicker.RubberSeekBar
  ...
  app:minValue=&quot;20&quot;
  app:maxValue=&quot;80&quot;
  app:elasticBehavior=&quot;cubic&quot;
  app:dampingRatio=&quot;0.3&quot;
  app:stiffness=&quot;300&quot;
  app:stretchRange=&quot;24dp&quot;
  app:defaultThumbRadius=&quot;16dp&quot;
  app:normalTrackWidth=&quot;4dp&quot;
  app:highlightTrackWidth=&quot;8dp&quot;
  app:normalTrackColor=&quot;#AAAAAA&quot;
  app:highlightTrackColor=&quot;#BA1F33&quot;
  app:defaultThumbInsideColor=&quot;#FFF&quot;
  app:highlightDefaultThumbOnTouchColor=&quot;#CD5D67&quot;/&gt;

&lt;!-- Similar attributes can be applied for RubberRangePicker as well--&gt;
&lt;com.jem.rubberpicker.RubberRangePicker
  ...
  app:minValue=&quot;0&quot;
  app:maxValue=&quot;100&quot;
  app:elasticBehavior=&quot;linear&quot;
  app:dampingRatio=&quot;0.4&quot;
  app:stiffness=&quot;400&quot;
  app:stretchRange=&quot;36dp&quot;
  app:defaultThumbRadius=&quot;16dp&quot;
  app:normalTrackWidth=&quot;4dp&quot;
  app:highlightTrackWidth=&quot;8dp&quot;
  app:normalTrackColor=&quot;#AAAAAA&quot;
  app:highlightTrackColor=&quot;#BA1F33&quot;
  app:defaultThumbInsideColor=&quot;#CFCD5D67&quot;
  app:highlightDefaultThumbOnTouchColor=&quot;#CD5D67&quot;/&gt;
</code></pre>
<p>或者，在代码中动态配置：</p>
<pre><code class="kotlin">val rubberSeekBar = RubberSeekBar(this)
rubberSeekBar.setMin(20)
rubberSeekBar.setMax(80)
rubberSeekBar.setElasticBehavior(ElasticBehavior.CUBIC)
rubberSeekBar.setDampingRatio(0.4F)
rubberSeekBar.setStiffness(1000F)
rubberSeekBar.setStretchRange(50f)
rubberSeekBar.setThumbRadius(32f)
rubberSeekBar.setNormalTrackWidth(2f)
rubberSeekBar.setHighlightTrackWidth(4f)
rubberSeekBar.setNormalTrackColor(Color.GRAY)
rubberSeekBar.setHighlightTrackColor(Color.BLUE)
rubberSeekBar.setHighlightThumbOnTouchColor(Color.CYAN)
rubberSeekBar.setDefaultThumbInsideColor(Color.WHITE)

val currentValue = rubberSeekBar.getCurrentValue()
rubberSeekBar.setCurrentValue(currentValue + 10)
rubberSeekBar.setOnRubberSeekBarChangeListener(object : RubberSeekBar.OnRubberSeekBarChangeListener &#123;
    override fun onProgressChanged(seekBar: RubberSeekBar, value: Int, fromUser: Boolean) &#123;&#125;
    override fun onStartTrackingTouch(seekBar: RubberSeekBar) &#123;&#125;
    override fun onStopTrackingTouch(seekBar: RubberSeekBar) &#123;&#125;
&#125;)


//Similarly for RubberRangePicker
val rubberRangePicker = RubberRangePicker(this)
rubberRangePicker.setMin(20)
...
rubberRangePicker.setHighlightThumbOnTouchColor(Color.CYAN)

val startThumbValue = rubberRangePicker.getCurrentStartValue()
rubberRangePicker.setCurrentStartValue(startThumbValue + 10)
val endThumbValue = rubberRangePicker.getCurrentEndValue()
rubberRangePicker.setCurrentEndValue(endThumbValue + 10)
rubberRangePicker.setOnRubberRangePickerChangeListener(object: RubberRangePicker.OnRubberRangePickerChangeListener&#123;
    override fun onProgressChanged(rangePicker: RubberRangePicker, startValue: Int, endValue: Int, fromUser: Boolean) &#123;&#125;
    override fun onStartTrackingTouch(rangePicker: RubberRangePicker, isStartThumb: Boolean) &#123;&#125;
    override fun onStopTrackingTouch(rangePicker: RubberRangePicker, isStartThumb: Boolean) &#123;&#125;
&#125;)
</code></pre>
<p>更多、更详细的使用请看Github。</p>
<p>Github：<a target="_blank" rel="noopener" href="https://github.com/Chrisvin/RubberPicker">github.com/Chrisvin/Ru…</a></p>
<h3 id="9-Switcher"><a href="#9-Switcher" class="headerlink" title="9. Switcher"></a>9. Switcher</h3><p>一个炫酷的Switcher 切换动画库，真是的太可爱了，我前面也写过文章专门介绍过：</p>
<p><a target="_blank" rel="noopener" href="https://juejin.im/post/6844904088174329864">炫酷！从未见过如此Q弹的Switcher</a></p>
<p>它的灵感来自于 Dribble上<code>Oleg Frolov </code>的设计。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/bitvale/Switcher">github.com/bitvale/Swi…</a></p>
<h3 id="10-StfalconImageViewer"><a href="#10-StfalconImageViewer" class="headerlink" title="10. StfalconImageViewer"></a>10. StfalconImageViewer</h3><p><code>StfalconImageViewer</code>是一个图片查看库， 该库简单且可定制。它包含一个<code>全屏图像查看器</code>，<strong>具有共享的图像过渡支持</strong>，<code>捏合缩放功能</code>以及<code>滑动手势来关闭</code>手势。</p>
<p>Github文档说明了如何使用每个功能。同样值得注意的是：该库与所有最受欢迎的图像处理库（例如Picasso，Glide等）兼容。</p>
<p>所有可配置项如下：</p>
<pre><code class="kotlin">StfalconImageViewer.Builder&lt;String&gt;(this, images, ::loadImage)
            .withStartPosition(startPosition)
            .withBackgroundColor(color)
            //.withBackgroundColorResource(R.color.color)
            .withOverlayView(view)
            .withImagesMargin(R.dimen.margin)
            //.withImageMarginPixels(margin)
            .withContainerPadding(R.dimen.padding)
            //.withContainerPadding(R.dimen.paddingStart, R.dimen.paddingTop, R.dimen.paddingEnd, R.dimen.paddingBottom)
            //.withContainerPaddingPixels(padding)
            //.withContainerPaddingPixels(paddingStart, paddingTop, paddingEnd, paddingBottom)
            .withHiddenStatusBar(shouldHideStatusBar)
            .allowZooming(isZoomingAllowed)
            .allowSwipeToDismiss(isSwipeToDismissAllowed)
            .withTransitionFrom(targeImageView)
            .withImageChangeListener(::onImageChanged)
            .withDismissListener(::onViewerDismissed)
            .withDismissListener(::onViewerDismissed)
</code></pre>
<p>更详细的使用请看Github。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/stfalcon-studio/StfalconImageViewer">github.com/stfalcon-st…</a></p>
<h3 id="11-Broccoli"><a href="#11-Broccoli" class="headerlink" title="11. Broccoli"></a>11. Broccoli</h3><p><code>Broccoli</code>是一个show View Loading 库，也就是我常说的<strong>骨架屏</strong>，在内容加载的时候，显示一个占位符。</p>
<p>该库带有很平滑的动画效果，你可以配合RecyclerView一起使用，等待加载内容时，再也不枯燥了。</p>
<p>示例：</p>
<pre><code class="java">Broccoli broccoli = new Broccoli();

//add the default style placeholder
broccoli.addPlaceholders(&#39;activity&#39;, &#39;view_id&#39;, &#39;view_id&#39;); 

or 
//add the default style placeholder
broccoli.addPlaceholders(&#39;view1&#39;, &#39;view2&#39;, &#39;view3&#39;); 

or 

//add the custom style placeholder
broccoli.addPlaceholder(new PlaceholderParameter.Builder()
                        .setView(&#39;view&#39;)
                        .setAnimation(&#39;scaleAnimation&#39;);
                        .setDrawable(DrawableUtils.createRectangleDrawable(placeHolderColor, 0))
                        .build()); 

or
//add the custom style placeholder with gradient animation
broccoli.addPlaceholder(new PlaceholderParameter.Builder()
                        .setView(&#39;view&#39;)
                        .setDrawable(new BroccoliGradientDrawable(Color.parseColor(&quot;#DDDDDD&quot;),
                            Color.parseColor(&quot;#CCCCCC&quot;), 0, 1000, new LinearInterpolator())
                        .build()); 
broccoli.show();
</code></pre>
<p>更多使用请看Github。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/samlss/Broccoli">github.com/samlss/Broc…</a></p>
<h3 id="12-Orbit-MVI"><a href="#12-Orbit-MVI" class="headerlink" title="12. Orbit MVI"></a>12. Orbit MVI</h3><p>这是一个用于Kotlin和Android的Model-View-Intent （MVI）框架。它的灵感来自Jake Wharton，RxFeedback和Mosby的“Managing State with RxJava”。</p>
<p>根据ReadMe所说：</p>
<blockquote>
<p>Orbit在您的redux实现周围提供了尽可能小的结构，以使其易于使用，但您仍可以使用RxJava的强大功能。</p>
</blockquote>
<p>redux系统可能如下所示：</p>
<pre><code class="kotlin">data class State(val total: Int = 0)

data class AddAction(val number: Int)

sealed class SideEffect &#123;
    data class Toast(val text: String) : SideEffect()
&#125;

class CalculatorViewModel : OrbitViewModel&lt;State, SideEffect&gt; (State(), &#123;

    perform(&quot;addition&quot;)
        .on&lt;AddAction&gt;()
        .sideEffect &#123; post(SideEffect.Toast(&quot;Adding $&#123;event.number&#125;&quot;)) &#125;
        .reduce &#123;
            currentState.copy(currentState.total + event.number)
        &#125;

    ...
&#125;)
</code></pre>
<p>activity / fragment 中：</p>
<pre><code class="kotlin">// Example of injection using koin, your DI system might differ
private val viewModel by viewModel&lt;CalculatorViewModel&gt;()

override fun onCreate() &#123;
    ...
    addButton.setOnClickListener &#123; viewModel.sendAction(AddAction) &#125;
&#125;

override fun onStart() &#123;
    viewModel.connect(this, ::handleState, ::handleSideEffect)
&#125;

private fun handleState(state: State) &#123;
    ...
&#125;

private fun handleSideEffect(sideEffect: SideEffect) &#123;
    when (sideEffect) &#123;
        is SideEffect.Toast -&gt; toast(sideEffect.text)
    &#125;
&#125;
</code></pre>
<p>详细使用请看Github。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/babylonhealth/orbit-mvi">github.com/babylonheal…</a></p>
<h3 id="13-IndicatorScrollView"><a href="#13-IndicatorScrollView" class="headerlink" title="13. IndicatorScrollView"></a>13. IndicatorScrollView</h3><p>该库为<code>NestedScrollView</code>添加了逻辑，使它可以在滚动时，更改对指示器进行动态响应。</p>
<p>README文件包含开始项目所需的所有信息，例如如何使用<code>IndicatorScrollView</code>，<code>IndicatorView</code>和<code>IndicatorItem</code>。目前,它的版本为<code>1.0.2</code>，是根据Apache 2.0许可发布的。它支持API 16及更高版本。</p>
<p>文档示例很详细，更多使用相关请看Github。</p>
<p>Github： <a target="_blank" rel="noopener" href="https://github.com/skydoves/IndicatorScrollView">github.com/skydoves/In…</a></p>
<h3 id="14-Cyanea"><a href="#14-Cyanea" class="headerlink" title="14. Cyanea"></a>14. Cyanea</h3><p><code>Cyanea</code> 是一个Android 主题引擎库。</p>
<p>它允许那你动态更换应用主题，它内置了很多主题如：</p>
<ul>
<li><code>Theme.Cyanea.Dark</code></li>
<li><code>Theme.Cyanea.Dark.LightActionBar</code></li>
<li><code>Theme.Cyanea.Dark.NoActionBar</code></li>
<li><code>Theme.Cyanea.Light</code></li>
<li><code>Theme.Cyanea.Light.DarkActionBar</code></li>
<li><code>Theme.Cyanea.Light.NoActionBar</code></li>
</ul>
<p>更多详细信息请看Github。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/jaredrummler/Cyanea">github.com/jaredrummle…</a></p>
<h3 id="15-Android-MotionLayout-Carousel"><a href="#15-Android-MotionLayout-Carousel" class="headerlink" title="15. Android MotionLayout Carousel"></a>15. Android MotionLayout Carousel</h3><p><img src="http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1be2eaffa23942298f7adaca00f73c67~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p>
<p>这是一个示例项目，它展示了如何使用<code>MotionLayout</code>来实现一个炫酷的轮播图。</p>
<p>文档几乎没有任何说明，但是如果你最近也在探索MotionLayout，这将是一个很好示例。</p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/faob-dev/MotionLayoutCarousel">github.com/faob-dev/Mo…</a></p>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>以上就是本期的开源项目推荐，如果你也有好玩的、有趣的、强大的开源项目，也可以推荐给博主，欢迎评论区留言讨论。</p>

        </div>

    </div>

    

    

    

    

    

    
<nav class="article-nav">
  
    <a href="/2020/08/31/Android-10-Q-11-R-%E5%88%86%E5%8C%BA%E5%AD%98%E5%82%A8%E9%80%82%E9%85%8D/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          Android 10(Q)/11(R) 分区存储适配
        
      </div>
    </a>
  
  
    <a href="/2020/07/27/Android%E5%85%A8%E6%96%B0UI%E7%BC%96%E7%A8%8B-Jetpack-Compose-%E8%B6%85%E8%AF%A6%E7%BB%86%E6%95%99%E7%A8%8B-%E7%AC%AC1%E5%BC%B9/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">Android全新UI编程 - Jetpack Compose 超详细教程 第1弹</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <a class="share-item" target="_blank"
            href="https://twitter.com/share?text=这15个Android开源库，只有经常逛Github的才知道！ - ApocalypseBlog&url=http://example.com/2020/08/03/%E8%BF%9915%E4%B8%AAAndroid%E5%BC%80%E6%BA%90%E5%BA%93%EF%BC%8C%E5%8F%AA%E6%9C%89%E7%BB%8F%E5%B8%B8%E9%80%9BGithub%E7%9A%84%E6%89%8D%E7%9F%A5%E9%81%93%EF%BC%81/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>
        <a class="share-item" target="_blank"
            href="https://www.facebook.com/sharer.php?title=这15个Android开源库，只有经常逛Github的才知道！ - ApocalypseBlog&u=http://example.com/2020/08/03/%E8%BF%9915%E4%B8%AAAndroid%E5%BC%80%E6%BA%90%E5%BA%93%EF%BC%8C%E5%8F%AA%E6%9C%89%E7%BB%8F%E5%B8%B8%E9%80%9BGithub%E7%9A%84%E6%89%8D%E7%9F%A5%E9%81%93%EF%BC%81/">
            <box-icon name='facebook-square' type='logo' ></box-icon>
        </a>
        <!-- <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=这15个Android开源库，只有经常逛Github的才知道！ - ApocalypseBlog&url=http://example.com/2020/08/03/%E8%BF%9915%E4%B8%AAAndroid%E5%BC%80%E6%BA%90%E5%BA%93%EF%BC%8C%E5%8F%AA%E6%9C%89%E7%BB%8F%E5%B8%B8%E9%80%9BGithub%E7%9A%84%E6%89%8D%E7%9F%A5%E9%81%93%EF%BC%81/&pic=">
            <div class="n-icon n-icon-weibo"></div>
        </a> -->
    </section>

</article>









</div>
                </section>
            </section>

             
            <aside class="sidebar">
            
                
            </aside>
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            ApocalypseBlog &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori</a>
        </div>
    </div>

</footer>




<script src="/dist/build.js?1.14.0.js"></script>


<script src="/dist/custom.js?1.14.0.js"></script>









</body>

</html>